from flask import current_app, g, request
from flask_httpauth import HTTPTokenAuth
from itsdangerous import TimedJSONWebSignatureSerializer as Serializer, BadSignature, SignatureExpired

from apps.libs.error_code import AuthFailed, Forbidden

from collections import namedtuple

from apps.libs.scope import is_in_scope

import base64

User = namedtuple('User', ['uid'])

auth = HTTPTokenAuth()


@auth.verify_token
def verify_token(token):
    token = base64.b64decode(token).decode('utf-8')
    user_info = verify_auth_token(token)
    if not user_info:
        return False
    g.user = user_info
    return True


def verify_auth_token(token):
    s = Serializer(current_app.config['SECRET_KEY'])
    try:
        data = s.loads(token)
    except BadSignature:
        # 捕捉到验证失败异常
        raise AuthFailed(msg='token is invalid', error_code=115)
    except SignatureExpired:
        # token过期异常
        raise AuthFailed(msg='token is expired', error_code=115)

    uid = data['uid']
    # ac_type = data['type']
    # scope = data['scope']
    # allow = is_in_scope(scope, request.endpoint)
    # if not allow:
    #     raise Forbidden()
    return User(uid=uid)


def generate_auth_token(uid, expiration=7200):
    '''生成令牌'''
    s = Serializer(current_app.config['SECRET_KEY'], expires_in=expiration)
    token = s.dumps({
        'uid': uid
    }).decode('utf-8')
    return base64.b64encode(token.encode('utf-8')).decode('utf-8')
